package com.xiaoq.sites.repository.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import com.xiaoq.coms.util.MathUtil;
import com.xiaoq.vo.PagingVo;
import org.apache.commons.lang3.StringUtils;
import org.mongodb.morphia.Datastore;
import org.mongodb.morphia.query.Query;
import org.mongodb.morphia.query.UpdateOperations;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.stereotype.Repository;

import com.xiaoq.coms.util.IdGenerator;
import com.xiaoq.sites.entity.SitesEntity;
import com.xiaoq.sites.entity.SitesPointEntity;
import com.xiaoq.sites.repository.ISitesPointRepository;
import com.xiaoq.sites.repository.ISitesRepository;

@Repository
public class SitesPointRepositoryImpl implements ISitesPointRepository {
	
	private static final Logger LOG = LoggerFactory.getLogger(SitesPointRepositoryImpl.class);

	@Autowired
	private Datastore datastore;

	@Autowired
	MongoTemplate mongoTemplate;
	
	@Autowired
	private ISitesRepository sitesRepository;
	
	@Autowired
	private IdGenerator idGenerator;
	
	@Override
	public SitesPointEntity findById(String id) {
		return datastore.get(SitesPointEntity.class, id);
	}

	@Override
	public List<SitesPointEntity> findBySitesId(String sitesId) {
		Query<SitesPointEntity> sitesPointQuery = datastore.find(SitesPointEntity.class)
				.filter("sitesId", sitesId)
				.order("-recIndex");
		List<SitesPointEntity> sitesPointList = new ArrayList<>();
		sitesPointList = sitesPointQuery.asList();
		return sitesPointList;
	}

	@Override
	public List<SitesPointEntity> findByRouteId(String routeId) {
		Query<SitesPointEntity> sitesPointQuery = datastore.find(SitesPointEntity.class);
		sitesPointQuery.field("routeId").equal(routeId);
		return sitesPointQuery.asList();
	}

	@Override
	public List<SitesPointEntity> findBySitesPointIdList(List<String> sitesPointList) {
		Query<SitesPointEntity> sitesPointQuery = datastore.find(SitesPointEntity.class);
		sitesPointQuery.filter("id in", sitesPointList);
		return sitesPointQuery.asList();
	}

	@Override
	public SitesPointEntity findSitesPointId(String sitesPointId) {
		
		SitesPointEntity sitesPoint = datastore.get(SitesPointEntity.class, sitesPointId);
		return sitesPoint;

	}

	@Override
	public boolean addSitesPoint(SitesPointEntity sitesPointEntity) {
		String sitesId = sitesPointEntity.getSitesId();
		String pointName = sitesPointEntity.getName();
		Query<SitesPointEntity> sitesPointQuery = datastore.find(SitesPointEntity.class);
		sitesPointQuery.field("name").equal(pointName).field("sitesId").equal(sitesId);
		SitesEntity sites = sitesRepository.findById(sitesId);
		if (sites != null) {
			String id = sitesPointEntity.getId();
			if(StringUtils.isBlank(id)){
				id = idGenerator.nextId();
			}
			sitesPointEntity.setId(id);
			datastore.save(sitesPointEntity);
			return true;
		}
		LOG.info("不存在对应的景点");
		return false;
	}

	@Override
	public boolean delSitesPoints(String pointId) {
		if (StringUtils.isNotBlank(pointId)) {
			SitesPointEntity sitesPoint = datastore.get(SitesPointEntity.class, pointId);
			if(sitesPoint!=null){
				datastore.delete(sitesPoint);
				return true;
			}
		}

		return false;
	}

	@Override
	public boolean updateSitesPoint(SitesPointEntity sitesPoint) {
		String pointId = sitesPoint.getId();
		Query<SitesPointEntity> sitesPointQuery = datastore.createQuery(SitesPointEntity.class).field("_id")
				.equal(pointId);
		UpdateOperations<SitesPointEntity> sitesPointUpdate = datastore.createUpdateOperations(SitesPointEntity.class);
		if (sitesPoint.getSitesId() != null)
			sitesPointUpdate = sitesPointUpdate.set("sitesId", sitesPoint.getSitesId());
		if (sitesPoint.getName() != null)
			sitesPointUpdate = sitesPointUpdate.set("name", sitesPoint.getName());
		if (sitesPoint.getLongitude() != null)
			sitesPointUpdate = sitesPointUpdate.set("longitude", sitesPoint.getLongitude());
		if (sitesPoint.getLatitude() != null)
			sitesPointUpdate = sitesPointUpdate.set("latitude", sitesPoint.getLatitude());
		if (sitesPoint.getIntroduction() != null)
			sitesPointUpdate = sitesPointUpdate.set("introduction", sitesPoint.getIntroduction());
		if (sitesPoint.getDetailInfo() != null)
			sitesPointUpdate = sitesPointUpdate.set("detailInfo", sitesPoint.getDetailInfo());
		if (sitesPoint.getMainImgUrl() != null)
			sitesPointUpdate = sitesPointUpdate.set("mainImgUrl", sitesPoint.getMainImgUrl());
		if (sitesPoint.getImgUrls() != null)
			sitesPointUpdate = sitesPointUpdate.set("imgUrls", sitesPoint.getImgUrls());
		if (sitesPoint.getTags() != null)
			sitesPointUpdate = sitesPointUpdate.set("tags", sitesPoint.getTags());
		if (sitesPoint.getRecIndex() != null)
			sitesPointUpdate = sitesPointUpdate.set("recIndex", sitesPoint.getRecIndex());
		if (sitesPoint.getFeatures() != null)
			sitesPointUpdate = sitesPointUpdate.set("features", sitesPoint.getFeatures());
		sitesPointUpdate = sitesPointUpdate.set("updatedAt", System.currentTimeMillis());

		datastore.update(sitesPointQuery, sitesPointUpdate);

		return true;
	}

	@Override
	public List<SitesPointEntity> findByPointNameVag(String pointName,String sitesId) {
		Query<SitesPointEntity> sitesPointQuery = datastore.find(SitesPointEntity.class);
		sitesPointQuery.field("sitesId").equal(sitesId);
		sitesPointQuery.field("name").contains(pointName);
		
		List<SitesPointEntity> sitesPointList = new ArrayList<>();
		sitesPointList = sitesPointQuery.asList();
		return sitesPointList;
	}

	@Override
	public SitesPointEntity findByPointName(String pointName) {
		Query<SitesPointEntity> sitesPointQuery = datastore.find(SitesPointEntity.class);
		sitesPointQuery.field("name").equal(pointName);
		SitesPointEntity sitesPoint = null;
		sitesPoint = sitesPointQuery.get();
		return sitesPoint;
	}

	@Override
	public List<SitesPointEntity> findMPlayPointBySitesId(String sitesId) {
		Query<SitesPointEntity> sitesPointQuery = datastore.find(SitesPointEntity.class)
				.filter("sitesId", sitesId).filter("recIndex >", 0)
				.order("-recIndex");
		return sitesPointQuery.asList();
	}

	@Override
	public List<SitesPointEntity> getSitesPointByPoint(double latitude, double longitude, long nearM, PagingVo pagingVo) {
		double distance = nearM / MathUtil.METER_2_MONGO_DISTANCE;
		Query<SitesPointEntity> sitesPointQuery =  datastore.find(SitesPointEntity.class)
				.field("loc").near(longitude, latitude, distance);
		if (pagingVo != null){
			sitesPointQuery.offset(pagingVo.getPageOffset()).limit(pagingVo.getPs());
		}
		return sitesPointQuery.asList();
	}

	@Override
	public boolean findPointName(String pointName, String sitesId) {
		Query<SitesPointEntity> sitesPointQuery = datastore.find(SitesPointEntity.class);
		sitesPointQuery.field("name").equal(pointName).field("sitesId").equal(sitesId);
		if(sitesPointQuery!=null&&sitesPointQuery.count()!=0){
			return true;
		}
		return false;
	}
}
